﻿using ServiceStack.Logging;
using ServiceStack.ServiceInterface.ServiceModel;
using System;
using System.IO;

namespace DocuSignPlugin
{
    
    public class SigningService : BaseDocuSignService
    {


        private static readonly ILog _log = LogManager.GetLogger(typeof(SigningService));


        public object Post(Login request)
        {
            try
            {
                if (request.Uri == 0)
                {
                    throw new Exception("Record Uri missing from 'Signing Complete' URL.");
                }

                LoginDetails credentials = Docusign.login(request.UserName, request.Password);

                this.TrimHelper.setUserCredentials(credentials, Response);

                _log.Debug("AcctId : " + credentials.AccountId);
                _log.Debug("BaseUri : " + credentials.BaseUrl);

                if (credentials.IsSet())
                {
                    Response.Cookies.AddPermanentCookie("docusign.auth", credentials.AccessToken, true);
                    return signDocument(request, credentials);
                }
                else
                {
                    throw new AuthenticationException("Invalid username or password entered.");
                }

            }
            catch (AuthenticationException authEx)
            {
                _log.Debug(authEx.Message, authEx);
                return new DSErrorResponse() { ResponseStatus = new ResponseStatus() { Message = authEx.Message, ErrorCode = "AUTH" } };
            }
            catch (Exception ex)
            {
                _log.Debug(ex.Message, ex);
                return new DSErrorResponse() { ResponseStatus = new ResponseStatus() { Message = ex.Message } };
            }

        }

        public object Get(Signing request)
        {
            LoginDetails loginDetails = this.TrimHelper.getUserCredentials(Request);

            if (!loginDetails.IsLoggedIn())
            {
                return new DSSigningResponse() { Uri = request.Uri };
            }
            else
            {
                if (!loginDetails.IsSet())
                {
                    Docusign.getDocusignDetails(loginDetails);

                    TrimHelper.setUserCredentials(loginDetails, Response);

                    return signDocument(request, loginDetails);
                }
                else
                {
                    return signDocument(request, loginDetails);
                }

                
             }
        }

        private object signDocument(ISigningRequest request, LoginDetails loginDetails)
        {
            string errorMessage = null;

            try
            {
                string fileNpath = TrimHelper.checkOut(Convert.ToInt64(request.Uri));

                _log.Debug("Checkout Successful. Path/Name : " + fileNpath);

                string recipientName = TrimHelper.GetUserName();
                string recipientEmail = TrimHelper.GetUserEmailAddress();


                if (File.Exists(fileNpath))
                {
                    string envGuid = Docusign.getEnvelopeGUID(loginDetails, fileNpath, TrimHelper.getDocName(request.Uri), recipientEmail, recipientName);

                    this.SetEnvGuid(request.Uri, envGuid);

                    _log.Debug("envGuid : " + envGuid);

                    if (envGuid != null)
                    {
                        string viewUrl = Docusign.getViewURL(loginDetails, envGuid, recipientEmail, recipientName, request.Uri, Request);
                        _log.Debug("viewUrl : " + viewUrl);
                        if (viewUrl != null)
                        {                            
                            return new DSSigningResponse() { Uri = request.Uri, ViewUrl = viewUrl };
                        }
                        else
                        {
                            errorMessage = "Unable to Generate Signature Page.";
                        }
                    }
                    else
                    {
                        errorMessage = "Unable to Generate an Envelope.";
                    }

                }
                else
                {
                    errorMessage = "Document Not Found.";
                }
            }

            catch (Exception ex)
            {
                errorMessage = ex.Message;

                // we get an error here we undo the checkout.
                TrimHelper.UndoCheckout(request.Uri);
            }

            return new DSErrorResponse() { ResponseStatus = new ResponseStatus() { Message = errorMessage } };
        }
    }
}
